package sfeir.ergosum;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;

import sfeir.ergosum.adapter.AddressAdapter;
import sfeir.ergosum.adapter.DetailsListAdapter;
import sfeir.ergosum.adapter.GalleryAdapter;
import sfeir.ergosum.adapter.MailAdapter;
import sfeir.ergosum.adapter.NetworkListAdapter;
import sfeir.ergosum.adapter.PhoneAdapter;
import sfeir.ergosum.dao.DatabaseConnection;
import sfeir.ergosum.dao.DatabaseProvider;
import sfeir.ergosum.dao.RemoteProvider;
import sfeir.ergosum.model.Address;
import sfeir.ergosum.model.Contact;
import sfeir.ergosum.model.Email;
import sfeir.ergosum.model.Person;
import sfeir.ergosum.model.Tel;
import sfeir.ergosum.myprofile.MyProfileNetworkActivity;
import sfeir.ergosum.myprofile.NewProfileActivity;
import sfeir.ergosum.tools.CachedImageView;
import sfeir.ergosum.tools.MicroformatDomParser;
import sfeir.ergosum.tools.SpreadsheetClient;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Contacts;
import android.provider.Contacts.People;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Gallery;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class MyProfileActivity extends Activity {
    private static final int MENU_QR = 0;
    private static final int MENU_SMS = 1;
    private static final int MENU_EMAIL = 2;
    private static final int MENU_EXPORT = 3;
    private static final int MENU_EDIT = 4;
    private static final int MENU_UPDATE = 5;
    private Contact contact;
    private ProgressDialog mProgress;
    private SpreadsheetClient mSpreadsheetClient;
    private Person p;

    private Boolean actionPhone;

    protected String defaultTel = null;

    private LayoutInflater mInflater;

    // private static DetailsListAdapter adapter;

    private static class ViewHolder {
        CachedImageView picture;
        TextView name;
        TextView title;
        TextView organisation;
    }

    private void initializeSpreadsheetClient() {
        final String key = this.getIntent().getStringExtra("key");
        if (key.endsWith(".tel")) {
            new Handler().post(new Runnable() {
                @Override
                public void run() {
                    mProgress
                            .setMessage(getString(R.string.profile_getting_details));
                    mProgress.setProgress(1000);
                    Person p = new MicroformatDomParser(key).getPerson();
                    contact = new Contact(p.getFullName(), key);
                    contact.setPerson(p);
                    mProgress.dismiss();
                    showContactProfile(contact);
                }
            });
            return;
        }
        mSpreadsheetClient = new SpreadsheetClient(
                new SpreadsheetClient.ResponseHandler() {
                    @Override
                    public void handleMessage(Message msg) {
                        switch (msg.what) {
                        case R.id.httpclient_ready:
                            mProgress
                                    .setMessage(getString(R.string.profile_getting_details));
                            mProgress.setProgress(1000);
                            mSpreadsheetClient.handler.obtainMessage(
                                    R.id.request_init, key).sendToTarget();
                            break;
                        case R.id.client_get_person:
                            mProgress.dismiss();
                            Person p = (Person) msg.obj;
                            contact = new Contact(p.getFullName(), key);
                            contact.setPerson(p);
                            showContactProfile(contact);
                            mSpreadsheetClient.terminate();
                            mSpreadsheetClient = null;
                            break;
                        default:
                            super.handleMessage(msg);
                            break;
                        }
                    }
                });
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.contact_profile);
        setTheme(R.style.ListTheme);

        contact = (Contact) getIntent().getSerializableExtra("contact");
        actionPhone = getIntent().getBooleanExtra("actionPhone", true);

        if (null != contact) {
            showContactProfile(contact);
        } else {
            mProgress = ProgressDialog.show(MyProfileActivity.this,
                    getString(R.string.loading), "", false);
            initializeSpreadsheetClient();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        if (null != mSpreadsheetClient && !mSpreadsheetClient.isAlive())
            mSpreadsheetClient.start();
    }

    protected void showContactProfile(Contact contact) {

        if (contact.getPerson() != null) {
            p = contact.getPerson();
            ListView list = (ListView) findViewById(android.R.id.list);
            TextView text = (TextView) findViewById(android.R.id.empty);
            mInflater = LayoutInflater.from(MyProfileActivity.this);

            LinearLayout basics = (LinearLayout) findViewById(R.id.basics);
            ViewHolder holder;

            basics = (LinearLayout) mInflater.inflate(
                    R.layout.contact_mini_card, basics, true);

            holder = new ViewHolder();
            holder.picture = (CachedImageView) basics
                    .findViewById(R.id.picture);
            holder.name = (TextView) basics.findViewById(R.id.name);
            holder.title = (TextView) basics.findViewById(R.id.title);
            holder.organisation = (TextView) basics
                    .findViewById(R.id.organisation);

            basics.setTag(holder);

            holder.name.setText(contact.getAlias());
            if (p != null) {
                holder.title.setText(p.getTitle());
                holder.organisation.setText(p.getCompany());
                holder.picture
                        .generatedImageFromUrl(p.getPhoto().getImageUrl());
            }

            text.setText("");
            DetailsListAdapter detailsAdapter = new DetailsListAdapter(
                    MyProfileActivity.this, p);
            detailsAdapter.setActionPhone(actionPhone);

            list.setAdapter(detailsAdapter);

            Gallery manege = (Gallery) findViewById(R.id.manege);

            manege.setAdapter(new GalleryAdapter(this));
            manege.setSelection(GalleryAdapter.ALL, true);

            manege.setOnItemClickListener(new OnItemClickListener() {
                @SuppressWarnings("unchecked")
                public void onItemClick(AdapterView parent, View v,
                        int position, long id) {
                    ListView list = (ListView) findViewById(android.R.id.list);
                    TextView text = (TextView) findViewById(android.R.id.empty);
                    switch (position) {
                    case GalleryAdapter.MAIL:
                        text.setText("");
                        MailAdapter mailAdapter = new MailAdapter(
                                MyProfileActivity.this, p);
                        list.setAdapter(mailAdapter);
                        break;
                    case GalleryAdapter.ADDRESS:
                        text.setText("");
                        AddressAdapter addressAdapter = new AddressAdapter(
                                MyProfileActivity.this, p);
                        list.setAdapter(addressAdapter);
                        break;
                    case GalleryAdapter.PHONE:
                        text.setText("");
                        PhoneAdapter phoneAdapter = new PhoneAdapter(
                                MyProfileActivity.this, p);
                        list.setAdapter(phoneAdapter);
                        break;
                    case GalleryAdapter.WEB:
                        text.setText("");
                        NetworkListAdapter netAdapter = new NetworkListAdapter(
                                MyProfileActivity.this, p);
                        list.setAdapter(netAdapter);
                        break;
                    case GalleryAdapter.ABOUT:
                        list.removeAllViewsInLayout();
                        text.setText(p.getAboutMe());
                        break;
                    case GalleryAdapter.ALL:
                        DetailsListAdapter detailsAdapter = new DetailsListAdapter(
                                MyProfileActivity.this, p);
                        detailsAdapter.setActionPhone(actionPhone);
                        list.setAdapter(detailsAdapter);
                        break;
                    }
                    // Toast.makeText(MyProfileActivity.this,
                    // "click element n�" + position, 1000).show();
                }
            });
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0, MENU_QR, 2, getString(R.string.profile_menu_qr)).setIcon(
                R.drawable.qrcode);
        menu.add(0, MENU_SMS, 3, getString(R.string.profile_menu_sms)).setIcon(
                R.drawable.share_sms);
        menu.add(0, MENU_EMAIL, 4, getString(R.string.profile_menu_email))
                .setIcon(R.drawable.share_email);
        menu.add(0, MENU_EXPORT, 1, getString(R.string.profile_menu_export))
                .setIcon(R.drawable.export_contact);
        if (getIntent().getExtras().get("key") != null)
            menu.add(0, MENU_EDIT, 0, getString(R.string.profile_menu_edit))
                    .setIcon(R.drawable.graphic_design);
        menu.add(0, MENU_UPDATE, 5, getString(R.string.profile_menu_update))
                .setIcon(R.drawable.refresh);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case MENU_QR:
            Intent intent = new Intent(this, QrifiedContactUrlActivity.class);
            intent.putExtra("CONTACT_URL", contact.getUrl());// http://spreadsheets.google.com/pub?key=prRhqeaLo__12J7YDzxJcbw
            startActivity(intent);
            return true;
        case MENU_SMS:
            Intent sendIntent = new Intent(Intent.ACTION_VIEW);
            sendIntent.putExtra("sms_body", getString(R.string.sms_text,
                    getString(R.string.sms_tag), contact.getUrl(), contact
                            .getPerson().getFullName()));
            sendIntent.setType("vnd.android-dir/mms-sms");
            startActivity(sendIntent);
            return true;
        case MENU_EMAIL:
            Intent i = new Intent(this, SendMailActivity.class);
            i.putExtra("CONTACT_URL", contact.getUrl());
            i.putExtra("CONTACT_ALIAS", contact.getAlias());
            startActivity(i);
            return true;
        case MENU_EXPORT:
            if (contact.getPhoneId() == (-1)) {
                exportContact();
            }
            return true;
        case MENU_EDIT:
            startActivity(new Intent(this, NewProfileActivity.class).putExtra(
                    "contact", contact));
            return true;
        case MENU_UPDATE:
            DatabaseProvider dp = new DatabaseProvider(new DatabaseConnection(
                    this));
            Person newPerson = RemoteProvider
                    .getUpdatedPerson(contact.getUrl());
            if (newPerson != null && contact.getPerson() != null) {
                newPerson.setId(contact.getPerson().getId());
                contact.setPerson(newPerson);

                dp.open();
                String oldImageUrl = dp.getPerson(contact.getPerson().getId())
                        .getPhoto().getImageUrl();
                this.deleteFile(CachedImageView.md5(oldImageUrl));
                dp.updateFullContactWithTimestamp(contact);
                dp.close();

                MyProfileActivity.this.setResult(RESULT_OK);
                getIntent().putExtra("contact", contact);
                // currentTab = getTabHost().getCurrentTab();
                this.onCreate(null);

                Toast.makeText(
                        this,
                        getString(R.string.profile_update_success, contact
                                .getAlias()), 1000).show();
            } else
                Toast.makeText(
                        this,
                        getString(R.string.profile_update_failure, contact
                                .getAlias()), 1000).show();
            return true;
        default:
            break;
        }
        return super.onOptionsItemSelected(item);
    }

    public void refresh(Contact c) {
        MyProfileNetworkActivity.refresh(c.getPerson());
    }

    /*
     * Export all possible contact's informations to the Contacts of the phone.
     */
    private void exportContact() {

        Person p = contact.getPerson();

        ContentResolver resolver = getContentResolver();

        // Creating contact
        ContentValues values = new ContentValues();
        values.put(People.NAME, p.getFullName());
        values.put(People.NOTES, p.getAboutMe());

        // Uri uri = resolver.insert(People.CONTENT_URI, values); //insert in
        // AllContacts
        // values.put(People.STARRED, 1);//By default MyContacts is displayed,
        // thus star the contact to be able to see it.

        Uri uri = Contacts.People.createPersonInMyContactsGroup(
                getContentResolver(), values);// insert
        // in
        // MyContacts
        // group

        Uri phoneUri = Uri.withAppendedPath(uri,
                People.Phones.CONTENT_DIRECTORY);
        Uri emailUri = Uri.withAppendedPath(uri,
                People.ContactMethods.CONTENT_DIRECTORY);
        Uri orgUri = Uri.withAppendedPath(uri,
                Contacts.Organizations.CONTENT_DIRECTORY);
        Uri addressUri = Uri.withAppendedPath(uri,
                Contacts.People.ContactMethods.CONTENT_DIRECTORY);

        long contactId = Long.parseLong(uri.getLastPathSegment());

        DatabaseProvider dp = new DatabaseProvider(new DatabaseConnection(
                MyProfileActivity.this));
        dp.open();
        contact.setPhoneId(contactId);
        dp.updateContactOnly(contact);
        dp.close();
        List<Tel> listTel = p.getTels();
        if (listTel.size() > 1)
            defaultTel = listTel.get(0).getPhoneNumber();
        // Adding phone
        for (Tel t : listTel) {
            values.clear();
            if (t.getType() == Tel.MOBILE_LINE) {
                values.put(People.Phones.TYPE, People.Phones.TYPE_MOBILE);
                defaultTel = t.getPhoneNumber();
            } else if (t.getType() == Tel.HOME_LANDLINE)
                values.put(People.Phones.TYPE, People.Phones.TYPE_HOME);
            else if (t.getType() == Tel.PROFESSIONNAL_LINE)
                values.put(People.Phones.TYPE, People.Phones.TYPE_WORK);

            values.put(People.Phones.NUMBER, t.getPhoneNumber());
            resolver.insert(phoneUri, values);
        }

        // Adding mail
        for (Email e : p.getEmails()) {
            values.clear();
            values.put(People.ContactMethods.KIND, Contacts.KIND_EMAIL);
            if (e.getTypeEmail() == Email.PERSONAL_EMAIL)
                values.put(People.ContactMethods.TYPE,
                        People.ContactMethods.TYPE_HOME);
            else if (e.getTypeEmail() == Email.PROFESSIONNAL_EMAIL)
                values.put(People.ContactMethods.TYPE,
                        People.ContactMethods.TYPE_WORK);
            else if (e.getTypeEmail() == Email.UNKNOWN)
                values.put(People.ContactMethods.TYPE,
                        People.ContactMethods.TYPE_OTHER);

            values.put(People.ContactMethods.DATA, e.getEmail());
            resolver.insert(emailUri, values);
        }

        // Adding organization
        values.clear();
        values.put(Contacts.Organizations.COMPANY, p.getCompany());
        values.put(Contacts.Organizations.TYPE,
                Contacts.Organizations.TYPE_WORK);
        resolver.insert(orgUri, values);

        // Adding adresses
        for (Address a : p.getAddresses()) {
            values.clear();
            values.put(Contacts.ContactMethods.KIND, Contacts.KIND_POSTAL);
            if (a.getType() == Address.PERSONAL_ADDRESS)
                values.put(Contacts.ContactMethods.TYPE,
                        Contacts.ContactMethods.TYPE_HOME);
            else if (a.getType() == Address.PROFESSIONNAL_ADDRESS)
                values.put(Contacts.ContactMethods.TYPE,
                        Contacts.ContactMethods.TYPE_WORK);
            else if (a.getType() == Address.DEFAULT_ADDRESS)
                values.put(Contacts.ContactMethods.TYPE,
                        Contacts.ContactMethods.TYPE_CUSTOM);

            values.put(Contacts.ContactMethods.DATA, a.getFullValue());
            resolver.insert(addressUri, values);
        }

        // Creating the image byte array to export it
        String urlPhoto = p.getPhoto().getImageUrl();

        if (urlPhoto != null) {
            String urlHash = CachedImageView.md5(urlPhoto);

            try {
                FileInputStream fis = openFileInput(urlHash);
                byte[] buffer = new byte[fis.available()];
                fis.read(buffer);
                Contacts.People.setPhotoData(resolver, uri, buffer);
            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (uri != null && phoneUri != null && emailUri != null
                && orgUri != null && addressUri != null)
            Toast.makeText(
                    this,
                    getString(R.string.profile_export_success, contact
                            .getAlias()), 1000).show();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (defaultTel != null && keyCode == KeyEvent.KEYCODE_CALL) {
            Intent i = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:"
                    + defaultTel));
            startActivity(i);
            return true;
        }
        return super.onKeyDown(keyCode, event);

    }
}
